package isMonitor;

import isDim.dimCargo;

import java.io.IOException;
import java.util.concurrent.BlockingQueue;

import Config.ConfigReader;
import Server.Client;

public class InternalProcessMonitor implements Runnable{

	private BlockingQueue<dimCargo> dimBox;
	private BlockingQueue<Boolean> dimPong;
	private int dimWaitingPongs;
	private boolean dimOk;
	private boolean estimationExchangerOk;
	
	private boolean evExOk;
	private int EventExchanger_pingListeningPort;
	
	private static final int PING_TIME = 3*60;
	private static final int MONITOR_ERROR = 50;
	private static final int MAX_DIM_WAITING_PONGS = 3;
	
	private int EstimationExchanger_pingListeningPort; 
	
	
	public InternalProcessMonitor(BlockingQueue<dimCargo> dBox, BlockingQueue<Boolean> dPong){
		dimBox = dBox;
		dimPong = dPong;
		dimWaitingPongs = 0;
		dimOk = true;
		estimationExchangerOk = true;
		evExOk = true;
		
		try {
			EstimationExchanger_pingListeningPort = ConfigReader.getInt("EstimationExchanger_pingListeningPort");
			EventExchanger_pingListeningPort = ConfigReader.getInt("EventExchanger_pingListeningPort");		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	public void run()
	{
		while (true)
		{
			try{
				Thread.sleep(PING_TIME*1000);
			}catch(Exception e){ System.out.println("FATAL ERROR. Error sleeping Monitor thread: " + e.getMessage()); System.exit(MONITOR_ERROR);}
			
			System.out.println("Sending internal pings.");
			
			runDimMonitoring();
			//runEstimationExchangerMonitor();
			//runEvExMonitoring();
		}
	}
	
	private void runDimMonitoring()
	{
		try{
			dimBox.put(new dimCargo(dimCargo.Type.PING));
		}catch(Exception e){ System.out.println("Error generating dimPing: " + e.getMessage()); return; }
		dimWaitingPongs++;
		
		dimWaitingPongs -= dimPong.size();
		dimPong.clear();
		
		if (dimWaitingPongs > MAX_DIM_WAITING_PONGS) dimOk = false;
		else dimOk = true;
	}
	
	private void runEstimationExchangerMonitor()
	{
        // hacemos ping  (el servidor est� siempre en localhost, porque es un thread)
        Client pingClient = new Client("localhost", EstimationExchanger_pingListeningPort);
        String response = null;
        try {
            response = pingClient.sendMessage("PING!");
        } catch (IOException ex) {
        	estimationExchangerOk = false;
        }
        if(response==null) estimationExchangerOk = false;
        else if(response.equals("PONG!")) estimationExchangerOk = true;
	}
	
	private void runEvExMonitoring()
	{
		
		evExOk = false;
		Client sender = new Client("localhost",EventExchanger_pingListeningPort);
		
		try {
			String r = sender.sendMessage("PING");
			if (r != null)
			{
				evExOk = r.toUpperCase().contains("PONG");
			}
		} catch (IOException e) {

		}
		
		sender.close();
		sender = null;
	}
	
}
